/*****************************************Copyright(C)******************************************
****************************************** *********************************************
*------------------------------------------文件信息---------------------------------------------
* FileName          : RS485.c
* Author            : 张婷颖
* Version           : 1.0V
* Description       : 
*----------------------------------------历史版本信息-------------------------------------------
* History           :
* Description       :
*-----------------------------------------------------------------------------------------------
***********************************************************************************************/
/* Includes-----------------------------------------------------------------------------------*/
#include "RS485.h"
#include "stdbool.h"
/* Private define-----------------------------------------------------------------------------*/

/* Private typedef----------------------------------------------------------------------------*/

/* Private macro------------------------------------------------------------------------------*/

/* Private variables--------------------------------------------------------------------------*/
#if MODBUS_485

#if COIL                                                                     //定义modbus读取的线圈及寄存器地址和数量
uint16_t coil_addr[SUM_COIL_CON]=COIL_ADDR;
uint8_t coil_num[SUM_COIL_CON]=COIL_NUM;
#endif  /*COIL*/
#if REGISTER
uint16_t reg_addr[SUM_REG_CON]=REG_ADDR;
uint8_t reg_num[SUM_REG_CON]=REG_NUM;
#endif  /*REGISTER*/

INFO_COMBINATION m485_sum_info;
bool rx_finsh = 0;
int i_readcont = 0,j_readcont = 0;
#endif  /*MODBUS_485*/
/* Private function prototypes----------------------------------------------------------------*/

/* Private functions--------------------------------------------------------------------------*/
#if MODBUS_485
/************************************************
函数名称 ： M_Analyse_info
功    能 ： 分析接收到的信息帧
参    数 ： p 接收缓存首地址   len  接收数据长度
返 回 值 ： 无
*************************************************/
void RX_Analyse_info(uint8_t *p,uint8_t Len)
{
	rx_finsh = M_Analyse_info(p,Len,&m485_sum_info);                             //进入MODBUS解析过程,其他内容这里面都完成了
//	refresh_info(&m485_sum_info);
}
/************************************************
函数名称 ： RX_Parse_Data
功    能 ： 主循环分别解析处理接收的数据
参    数 ： m485_sum_info 协议解析后的数据
返 回 值 ： 无
*************************************************/
void RX_Parse_Data(INFO_COMBINATION *m485_sum_info)
{
#if NON_INTERRUPT_PROCESS
	if(rx_finsh)                                                                  //接收了新数据
	{
		rx_finsh = 0;
		switch(m485_sum_info->recvinfo.funcode)
		{
			case FUNCODE_01:
			case FUNCODE_02:
				if(M_check_code01_02(&(m485_sum_info->rx_data), &(m485_sum_info->tx_data),  m485_sum_info->rebuf))                  //返回错误，重发请求
				   rerequest(m485_sum_info);
				else
				{
					m485_sum_info->master_status = FINISH;                                                                //本次请求完成
				   refresh_info(m485_sum_info);                                                                          //清除本次请求 响应
				   m485_sum_info->send_count = 0;                                                                        //从站信息正常，清除重发次数
				}
				break;
			case FUNCODE_03:
			case FUNCODE_04:
				if(M_check_code03_04(&(m485_sum_info->rx_data), &(m485_sum_info->tx_data),  m485_sum_info->rebuf))                  //返回错误，重发请求
				   rerequest(m485_sum_info);
				else
				{
					m485_sum_info->master_status = FINISH;                                                                //本次请求完成
				   refresh_info(m485_sum_info);                                                                          //清除本次请求 响应
				   m485_sum_info->send_count = 0;                                                                        //从站信息正常，清除重发次数
				}
				break;
			case FUNCODE_05:
			case FUNCODE_06:
				if(M_check_code05_06(&(m485_sum_info->rx_data), &(m485_sum_info->tx_data), m485_sum_info->rebuf))                                      //返回错误，重发请求
				   rerequest(m485_sum_info);
				else
				{
					m485_sum_info->master_status = FINISH;                                               //本次请求完成
				   refresh_info(m485_sum_info);                                                       //清除本次请求 响应
				   m485_sum_info->send_count = 0;                                                       //从站信息正常，清除重发次数
				}
				break;
			case FUNCODE_0F:
			case FUNCODE_10:
				if(M_check_code0f_10(&(m485_sum_info->rx_data), &(m485_sum_info->tx_data),  m485_sum_info->rebuf))                                     //返回错误，重发请求
				   rerequest(m485_sum_info);
				else
				{
					m485_sum_info->master_status = FINISH;                                               //本次请求完成
				   refresh_info(m485_sum_info);                                                       //清除本次请求 响应
				   m485_sum_info->send_count = 0;                                                       //从站信息正常，清除重发次数
				}
				break;
			default:   break;
		}
	}
#endif  /*NON_INTERRUPT_PROCESS*/
}
/************************************************
函数名称 ： M485_read
功    能 ： MODBUS根据读取要求，读取线圈寄存器数据
参    数 ：
返 回 值 ： 无
*************************************************/
void M485_read(void)
{
	if(m485_sum_info.read_finish == 0)
	{
		#if COIL
		if(!i_readcont)//i_readcont 记录已经读取几组线圈数据   这里是读取第一组线圈
		{
			M_achieves_read(MODBUS_485_ADDR,FUNCODE_01,coil_addr[0],coil_num[0],&m485_sum_info);
			i_readcont++;
		}

		if ((m485_sum_info.master_status == FINISH)|
			(m485_sum_info.master_status == ABANDON_REQUEST))                                                //当上一次请求完成或放弃，更改请求，发送下一次请求
		{
			if(i_readcont < SUM_COIL_CON)
			{
				M_achieves_read(MODBUS_485_ADDR,FUNCODE_01,coil_addr[i_readcont],coil_num[i_readcont],&m485_sum_info);
				i_readcont++;
			}
		#if REGISTER & COIL
			else if((REGISTER)&(i_readcont >= SUM_COIL_CON)){
				if(j_readcont < SUM_REG_CON)
				{
					M_achieves_read(MODBUS_485_ADDR,FUNCODE_03,reg_addr[j_readcont],reg_num[j_readcont],&m485_sum_info);
					j_readcont++;
				}
				else
				{
					m485_sum_info.read_finish = 1;
					i_readcont = 0;
					j_readcont = 0;
//					m485_sum_info.read_finish = 0;                      //用于循环测试
				}
			}
		#elif                                                              //只有线圈
					else {
						m485_sum_info.read_finish = 1;
						i_readcont = 0;
						j_readcont = 0;
						m485_sum_info.read_finish = 0;                      //用于循环测试
					}
		#endif	/*REGISTER & COIL*/
		}
		#endif  /*COIL*/
#if REGISTER & (!COIL)                                             //无线圈时先从寄存器开始读取
		if(!i_readcont)
		{
			M_achieves_read(MODBUS_485_ADDR,FUNCODE_03,reg_addr[0],reg_num[0],&m485_sum_info);
			i_readcont++;
		}
		if ((m485_sum_info.master_status == FINISH)|
			(m485_sum_info.master_status == ABANDON_REQUEST))                                                //当上一次请求完成或放弃，更改请求，发送下一次请求
		{
			if(i_readcont < SUM_REG_CON)
			{
				M_achieves_read(MODBUS_485_ADDR,FUNCODE_03,reg_addr[i_readcont],reg_num[i_readcont],&m485_sum_info);
				i_readcont++;
			}
			else {
				m485_sum_info.read_finish = 1;
				i_readcont = 0;
				j_readcont = 0;
			}

		}
#endif  /*COIL*/
	}
}
#endif  /*MODBUS_485*/





